home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
snip9707.zip
/
BIGTEST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-05
|
5KB
|
182 lines
/* +++Date last modified: 05-Jul-1997 */
/* BIGTEST.C
**
** Routines to test Big Number Arithmetic functions found in BIGNUM.C
**
*/
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <time.h>
#if defined(_MSC_VER)
#include <memory.h>
#elif defined(__TURBOC__)
#include <mem.h>
#else
#include <string.h>
#endif
#include "bignum.h" /* Typedef for BigNum type */
ULong Big2Long(BigNum * b)
{
/* Converts the big number in b to an unsigned long. This is a support
** routine for test purposes only. The length of b should be 3 or less
** to avoid overflowing the long.
*/
int i;
ULong res = 0L;
for (i = 0; i < b->nlen; i++)
{
res *= (ULong) MODULUS;
res += (ULong) b->n[i];
}
return res;
}
void BigNumRand(BigNum **b)
{
/* This routine fills the big number pointed to by *b to a random long.
** It is a support routine for test purposes only.
*/
int i = (*b)->nlen - 1;
memset((*b)->n, 0, (*b)->nlen * sizeof(UShort));
if (i < 0)
return;
else if (i == 0)
(*b)->n[0] = rand() % MODULUS;
else if (i == 1)
{
(*b)->n[0] = rand() % MODULUS;
(*b)->n[1] = rand() % MODULUS;
}
else
{
(*b)->n[i--] = rand() % MODULUS;
(*b)->n[i--] = rand() % MODULUS;
(*b)->n[i] = rand() % 21;
}
}
int main(void)
{
/* Test the big number arithmetic routines using random longs. Runs
** until an error is encountered or a key pressed.
** Gives examples of how to call the routines.
*/
BigNum *a, *b, *c, *d = NULL, *p, *s;
ULong al, bl, cl, dl, sl, cnt = 0L;
/* 'Randomly' seed the rand() generator */
srand((unsigned int) time(NULL));
/* Create two big numbers */
a = BigNumAlloc(3);
b = BigNumAlloc(3);
do /* Loop until a key is pressed... */
{
if ((++cnt % 1000L) == 0) /* Show every 1000 iterations */
printf("%ld\n", cnt);
if (kbhit()) /* If a key pressed--we're outta here! */
{
getch();
break;
}
/* Make the two big numbers random... */
BigNumRand(&a);
BigNumRand(&b);
/* Get their 'long' values... */
al = Big2Long(a);
bl = Big2Long(b);
c = BigNumDiv(a, b, &d); /* Divide a by b */
if (c == NULL)
{
printf("Error: Divide did not return quotient\n");
break;
}
if (d == NULL)
{
printf("Error: Divide did not return remainder\n");
break;
}
cl = Big2Long(c); /* Get quotient as a long */
dl = Big2Long(d); /* Get remainder as a long */
if ((al / bl) != cl)
{
printf("Error: Quotient %lu / %lu != %lu\n", al, bl, cl);
printf("a = %d%04d%04d b = %d%04d\n",
a->n[0], a->n[1], a->n[2], b->n[0], b->n[1]);
break;
}
if ((al % bl) != dl)
{
printf("Error: Remainder %lu %c %lu != %lu\n",
al, '%', bl, dl);
printf("a = %d%04d%04d b = %d%04d\n",
a->n[0], a->n[1], a->n[2], b->n[0], b->n[1]);
break;
}
/* Reconstruct BigNum a by multiplying the quotient by b and
** adding the remainder.
*/
p = BigNumMul(c, b);
s = BigNumAdd(p, d);
sl = Big2Long(s);
if (sl != al)
{
printf("Error: Couldn't reconstruct original "
"divisor: %lu != %lu\n", al, sl);
break;
}
BigNumFree(s); /* To use s again, must free it first! */
s = BigNumSub(a, b);
if (al >= bl) /* For BigNumSub(), a must be > than b */
{
sl = Big2Long(s);
if (sl != (al - bl))
{
printf("Error: Subtraction error %lu - %lu != %lu\n",
al, bl, sl);
break;
}
}
else if (s != NULL)
{
printf("Invalid subtraction %lu - %lu\n", al, bl);
break;
}
/* Free all the memory allocated by the arithmetic calls */
BigNumFree(c);
BigNumFree(d);
BigNumFree(p);
BigNumFree(s);
} while (1);
BigNumFree(a);
BigNumFree(b);
return 0;
}